﻿using FyCaches.Core.Exceptions;
using FyCaches.Core.Msg;
using FyCaches.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FyCaches.Core
{
    class PackUtils
    {
        /// <summary>
        /// 对错误消息进行打包
        /// </summary>
        /// <param name="ex"></param>
        /// <returns></returns>
        internal static List<byte> CreatePackByException(byte[] requestId, Exception ex)
        {
            List<byte> res = new List<byte>();

            if (requestId == null)
                return null;

            try
            {
                CException ce = (CException)ex;
                res.AddRange(requestId);
                res.Add(0x01);
                res.AddRange(BitConverter.GetBytes(ce.Code));
                res.AddRange(Encoding.UTF8.GetBytes(ce.Message));
            }
            catch (Exception e)
            {
                res.AddRange(requestId);
                res.Add(0x01);
                res.AddRange(BitConverter.GetBytes(uint.MaxValue));
                res.AddRange(Encoding.UTF8.GetBytes(e.Message));
            }
            return res;
        }

        /// <summary>
        /// 对返回数字类型的数据进行打包
        /// </summary>
        /// <param name="requestId"></param>
        /// <param name="num"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        internal static List<byte> CreatePackByNumber(CommandInfo command, int num)
        {
            List<byte> res = new List<byte>();
            try
            {
                res.AddRange(command.RequestId);
                res.Add(0x00);
                res.AddRange(command.Command);
                res.AddRange(BitConverter.GetBytes(num));
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        /// <summary>
        /// 对返回字节数组类型的数据进行打包
        /// </summary>
        /// <param name="command"></param>
        /// <param name="cdata"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        internal static List<byte> CreatePackByByteArrary(CommandInfo command, byte[] cdata)
        {
            List<byte> res = new List<byte>();
            try
            {
                res.AddRange(command.RequestId);
                res.Add(0x00);
                res.AddRange(command.Command);
                if (cdata != null)
                    res.AddRange(cdata);
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        /// <summary>
        /// 对返回单字节的数据进行打包
        /// </summary>
        /// <param name="command"></param>
        /// <param name="b"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        internal static List<byte> CreatePackByByte(CommandInfo command, byte b)
        {
            List<byte> res = new List<byte>();
            try
            {
                res.AddRange(command.RequestId);
                res.Add(0x00);
                res.AddRange(command.Command);
                res.Add(b);
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }

        /// <summary>
        /// 打包推送数据
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        internal static List<byte> CreatePackForPublish(CommandInfo command, string topic, string subscribeTopic, ref byte[] clientId, ref byte[] msg)
        {
            List<byte> res = new List<byte>();
            try
            {
                res.AddRange(command.RequestId);
                res.Add(0x00);
                res.AddRange(command.Command);

                //推送的主题
                byte[] bTopic = Encoding.UTF8.GetBytes(topic);
                res.AddRange(BitConverter.GetBytes((ushort)bTopic.Length));
                res.AddRange(bTopic);

                //接收的主题
                bTopic = Encoding.UTF8.GetBytes(subscribeTopic);
                res.AddRange(BitConverter.GetBytes((ushort)bTopic.Length));
                res.AddRange(bTopic);

                //clientId
                res.AddRange(BitConverter.GetBytes((ushort)clientId.Length));
                res.AddRange(clientId);

                //内容
                res.AddRange(msg);
            }
            catch (Exception)
            {
                throw;
            }
            return res;
        }
    }
}
